package com.xuecheng.manage_course.service;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.xuecheng.framework.domain.cms.CmsPage;
import com.xuecheng.framework.domain.cms.response.CmsPageResult;
import com.xuecheng.framework.domain.cms.response.CmsPostPageResult;
import com.xuecheng.framework.domain.course.*;
import com.xuecheng.framework.domain.course.ext.CourseView;
import com.xuecheng.framework.domain.course.ext.TeachplanNode;
import com.xuecheng.framework.domain.course.request.CourseListRequest;
import com.xuecheng.framework.domain.course.response.AddCourseResult;
import com.xuecheng.framework.domain.course.response.CourseCode;
import com.xuecheng.framework.domain.course.response.CoursePublishResult;
import com.xuecheng.framework.exception.ExceptionCast;
import com.xuecheng.framework.model.response.CommonCode;
import com.xuecheng.framework.model.response.QueryResponseResult;
import com.xuecheng.framework.model.response.QueryResult;
import com.xuecheng.framework.model.response.ResponseResult;
import com.xuecheng.manage_course.client.CmsPageClient;
import com.xuecheng.manage_course.dao.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.transaction.Transactional;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author zhaoxiang
 * @version 1.0
 * @Date 2019/10/29 12:19
 */
@Service
public class CourseService {

    @Autowired
    private TeachplanMapper teachplanMapper;
    @Autowired
    private TeachplanRepository teachplanRepository;
    @Autowired
    private TeachPlanMediaRepository teachplanMediaRepository;
    @Autowired
    private TeachplanMediaPubRepository teachplanMediaPubRepository;
    @Autowired
    private CourseMapper courseMapper;
    @Autowired
    private CourseBaseRepository courseBaseRepository;
    @Autowired
    private CourseMarketRepository courseMarketRepository;
    @Autowired
    private CoursePicRepository coursePicRepository;
    @Autowired
    private CoursePubRepository coursePubRepository;
    @Autowired
    private CmsPageClient cmsPageClient;

    @Value("${course-publish.dataUrlPre}")
    private String publish_dataUrlPre;
    @Value("${course-publish.pagePhysicalPath}")
    private String publish_page_physicalpath;
    @Value("${course-publish.pageWebPath}")
    private String publish_page_webpath;
    @Value("${course-publish.siteId}")
    private String publish_siteId;
    @Value("${course-publish.templateId}")
    private String publish_templateId;
    @Value("${course-publish.previewUrl}")
    private String previewUrl;

    /**
     * 保存课程计划与媒资文件的关联信息
     *
     * @param teachplanMedia
     * @return
     */
    @Transactional
    public ResponseResult saveMedia(TeachplanMedia teachplanMedia){
        if (teachplanMedia == null || StringUtils.isEmpty(teachplanMedia.getTeachplanId())){
            ExceptionCast.cast(CommonCode.INVALID_PARAM);
        }
        //校验课程计划是否是3级
        //课程计划
        String teachplanId = teachplanMedia.getTeachplanId();
        //查询到课程计划
        Optional<Teachplan> optional = teachplanRepository.findById(teachplanId);
        if (!optional.isPresent()){
            ExceptionCast.cast(CommonCode.INVALID_PARAM);
        }
        //获取到课程计划
        Teachplan teachplan = optional.get();
        String grade = teachplan.getGrade();
        if (StringUtils.isEmpty(grade) || !"3".equals(grade)){
            //只允许选择第三级的课程计划关联视频
            ExceptionCast.cast(CourseCode.COURSE_MEDIA_TEACHPLAN_GRADEERROR);
        }
        //查询teachplanMedia
        Optional<TeachplanMedia> mediaOptional = teachplanMediaRepository.findById(teachplanId);
        TeachplanMedia teachplanMedia1 = null;
        if(mediaOptional.isPresent()){
            teachplanMedia1 = mediaOptional.get();
        }else{
            teachplanMedia1 = new TeachplanMedia();
        }
        //将teachplanMedia1保存到数据库
        teachplanMedia1.setCourseId(teachplan.getCourseid());//课程id
        teachplanMedia1.setMediaId(teachplanMedia.getMediaId());//媒资文件的id
        teachplanMedia1.setMediaFileOriginalName(teachplanMedia.getMediaFileOriginalName());//媒资文件的原始名称
        teachplanMedia1.setMediaUrl(teachplanMedia.getMediaUrl());//媒资文件的url
        teachplanMedia1.setTeachplanId(teachplanId);
        teachplanMediaRepository.save(teachplanMedia1);

        return new ResponseResult(CommonCode.SUCCESS);
    }
    /**
     * 获取课程详情页面数据信息
     * @param courseId
     * @return
     */
    public CourseView getCoruseView(String courseId){
        CourseView courseView = new CourseView();
        //查询课程基本信息
        Optional<CourseBase> oCourseBase = courseBaseRepository.findById(courseId);
        if (oCourseBase.isPresent()){
            courseView.setCourseBase(oCourseBase.get());
        }
        //查询课程图片信息
        Optional<CoursePic> oCoursePic = coursePicRepository.findById(courseId);
        if (oCoursePic.isPresent()){
            courseView.setCoursePic(oCoursePic.get());
        }
        //查询课程营销信息
        Optional<CourseMarket> oCourseMarket = courseMarketRepository.findById(courseId);
        if (oCourseMarket.isPresent()){
            courseView.setCourseMarket(oCourseMarket.get());
        }
        //查询课程节点信息
        TeachplanNode teachplanNode = teachplanMapper.selectList(courseId);
        courseView.setTeachplanNode(teachplanNode);
        return courseView;
    }

    /**
     * 根据id查询课程营销信息
     *
     * @param courseId
     * @return
     */
    public CourseMarket findCourseMarketById(String courseId) {
        Optional<CourseMarket> optional = courseMarketRepository.findById(courseId);
        if (!optional.isPresent()) {
            return null;
        }
        return optional.get();
    }

    /**
     * 修改课程营销信息
     *
     * @param courseId
     * @param courseMarket
     * @return
     */
    public CourseMarket updateCourseMarket(String courseId, CourseMarket courseMarket) {
        CourseMarket rCourseMarket = findCourseMarketById(courseId);
        if (rCourseMarket == null) {
            //rCourseMarket为空说明没有营销信息
            //添加课程营销信息
            rCourseMarket = new CourseMarket();
            BeanUtils.copyProperties(courseMarket, rCourseMarket);
            //设置课程id
            rCourseMarket.setId(courseId);
            courseMarketRepository.save(rCourseMarket);
        }
        rCourseMarket.setCharge(courseMarket.getCharge());
        rCourseMarket.setStartTime(courseMarket.getStartTime());//课程有效期，开始时间
        rCourseMarket.setEndTime(courseMarket.getEndTime());//课程有效期，结束时间
        rCourseMarket.setPrice(courseMarket.getPrice());
        rCourseMarket.setQq(courseMarket.getQq());
        rCourseMarket.setValid(courseMarket.getValid());
        CourseMarket save = courseMarketRepository.save(rCourseMarket);
        return save;
    }

    /**
     * 根基id查询课程信息
     *
     * @param courseId
     * @return
     */
    public CourseBase findCourseById(String courseId) {
        Optional<CourseBase> optional = courseBaseRepository.findById(courseId);
        if (!optional.isPresent()) {
            ExceptionCast.cast(CourseCode.COURSE_GET_NOTEXISTS);
            return null;
        }
        return optional.get();
    }

    /**
     * 修改课程基本信息
     *
     * @param courseId
     * @param courseBase
     * @return
     */
    @Transactional
    public ResponseResult updateCourseBase(String courseId, CourseBase courseBase) {
        CourseBase course = findCourseById(courseId);
        if (course == null) {
            ExceptionCast.cast(CommonCode.INVALID_PARAM);
        }
        //修改课程信息
        course.setName(courseBase.getName());
        course.setMt(courseBase.getMt());
        course.setSt(courseBase.getSt());
        course.setGrade(courseBase.getGrade());
        course.setStudymodel(courseBase.getStudymodel());
        course.setUsers(courseBase.getUsers());
        course.setDescription(courseBase.getDescription());
        courseBaseRepository.save(course);
        return new ResponseResult(CommonCode.SUCCESS);
    }

    /**
     * 新增课程信息
     *
     * @param courseBase
     * @return
     */
    @Transactional
    public AddCourseResult addCourseBase(CourseBase courseBase) {
        //课程状态默认为未发布 202001
        courseBase.setStatus("202001");
        courseBaseRepository.save(courseBase);
        return new AddCourseResult(CommonCode.SUCCESS, courseBase.getId());
    }

    /**
     * 查询课程图片信息
     *
     * @param courseId
     * @return
     */
    public CoursePic findCoursePic(String courseId) {
        Optional<CoursePic> optional = coursePicRepository.findById(courseId);
        if (!optional.isPresent()) {
            ExceptionCast.cast(CourseCode.COURSE_PIC_ISNOTEXIST);
        }
        return optional.get();
    }

    /**
     * 添加课程图片信息
     *
     * @param courseId
     * @param pic
     * @return
     */
    @Transactional
    public ResponseResult addCoursePic(String courseId, String pic) {
        //获取课程图片信息
        Optional<CoursePic> optional = coursePicRepository.findById(courseId);
        CoursePic coursePic = null;
        if (optional.isPresent()) {
            coursePic = optional.get();
        }
        if (coursePic == null) {
            coursePic = new CoursePic();
        }
        coursePic.setCourseid(courseId);
        coursePic.setPic(pic);
        //保存课程图片信息
        coursePicRepository.save(coursePic);
        return new ResponseResult(CommonCode.SUCCESS);
    }

    /**
     * 删除课程图片信息
     *
     * @param courseId
     * @return
     */
    @Transactional
    public ResponseResult deleteCoursePic(String courseId) {
        long result = coursePicRepository.deleteByCourseid(courseId);
        if (result > 0){
            return new ResponseResult(CommonCode.SUCCESS);
        }
        return new ResponseResult(CommonCode.FAIL);
    }

    /**
     * 查询课程计划
     *
     * @param courseId
     * @return
     */
    public TeachplanNode selectList(String courseId) {
        return teachplanMapper.selectList(courseId);
    }

    /**
     * 查询课程列表信息
     *
     * @param page
     * @param size
     * @param courseListRequest
     * @return
     */
    public QueryResponseResult findCourseList(String companyId, int page, int size, CourseListRequest courseListRequest) {
        if (courseListRequest == null) {
            courseListRequest = new CourseListRequest();
        }
        if (page <= 0) {
            page = 1;
        }
        if (size <= 0) {
            size = 10;
        }
        courseListRequest.setCompanyId(companyId);
        //设置分页参数
        PageHelper.startPage(page, size);
        //分页查询课程信息
        Page<CourseInfo> courseListPage = courseMapper.findCourseListPage2(courseListRequest);
        List<CourseInfo> list = courseListPage.getResult();
        long total = courseListPage.getTotal();
        QueryResult<CourseInfo> courseInfoQueryResult = new QueryResult<>();
        courseInfoQueryResult.setList(list);
        courseInfoQueryResult.setTotal(total);
        return new QueryResponseResult(CommonCode.SUCCESS, courseInfoQueryResult);
    }

    /**
     * 添加课程计划
     *
     * @param teachplan
     * @return
     */
    @Transactional
    public ResponseResult addTeachplan(Teachplan teachplan) {
        if (teachplan == null ||
                StringUtils.isEmpty(teachplan.getPname()) ||
                StringUtils.isEmpty(teachplan.getCourseid())) {
            ExceptionCast.cast(CommonCode.INVALID_PARAM);
        }
        //课程id
        String courseid = teachplan.getCourseid();
        //父节点id
        String parentid = teachplan.getParentid();
        if (StringUtils.isEmpty(parentid)) {
            //获取课程根节点
            parentid = getTeachplanRoot(courseid);
        }
        //查询根节点信息
        Optional<Teachplan> optional = teachplanRepository.findById(parentid);
        Teachplan teachplan1 = optional.get();
        //父节点的级别
        String parent_grade = teachplan1.getGrade();
        //创建一个新节点准备添加
        Teachplan teachplanNew = new Teachplan();
        //将teachplan属性拷贝到teachplanNew中
        BeanUtils.copyProperties(teachplan, teachplanNew);
        //设置必要的属性
        teachplanNew.setParentid(parentid);
        if ("1".equals(parent_grade)) {
            teachplanNew.setGrade("2");
        } else {
            teachplanNew.setGrade("3");
        }
        teachplanNew.setStatus("0");//未发布
        teachplanRepository.save(teachplanNew);
        return new ResponseResult(CommonCode.SUCCESS);

    }

    /**
     * 获取课程的根节点
     *
     * @param courseId
     * @return
     */
    public String getTeachplanRoot(String courseId) {
        Optional<CourseBase> optional = courseBaseRepository.findById(courseId);
        if (!optional.isPresent()) {
            return null;
        }
        CourseBase courseBase = optional.get();
        //调用dao查询teachplan表得到该课程的根节点（一级节点）
        List<Teachplan> teachplanList = teachplanRepository.findByCourseidAndParentid(courseId, "0");
        if (teachplanList == null || teachplanList.size() <= 0) {
            //新增一个课程的根节点
            Teachplan teachplan = new Teachplan();
            teachplan.setCourseid(courseId);
            teachplan.setParentid("0");
            teachplan.setGrade("1");//一级节点 root节点
            teachplan.setStatus("0");//状态 未发布
            teachplan.setPname(courseBase.getName());
            teachplanRepository.save(teachplan);
            return teachplan.getId();
        }
        //返回根节点的id
        return teachplanList.get(0).getId();
    }

    /**
     * 课程预览
     * @param courseId
     * @return
     */
    public CoursePublishResult preview(String courseId){
        //请求cms添加页面
        CourseBase rCourseBase = findCourseById(courseId);
        //准备cmsPage页面
        CmsPage cmsPage = new CmsPage();
        //站点
        cmsPage.setSiteId(publish_siteId);//课程预览站点
        //模板
        cmsPage.setTemplateId(publish_templateId);
        //页面名称
        cmsPage.setPageName(courseId+".html");
        //页面别名
        cmsPage.setPageAliase(rCourseBase.getName());
        //页面访问路径
        cmsPage.setPageWebPath(publish_page_webpath);
        //页面存储路径
        cmsPage.setPagePhysicalPath(publish_page_physicalpath);
        //数据url
        cmsPage.setDataUrl(publish_dataUrlPre+courseId);
        //Feign远程请求cms保存页面信息
        CmsPageResult cmsPageResult = cmsPageClient.saveCmsPage(cmsPage);
        if (!cmsPageResult.isSuccess()){
            return new CoursePublishResult(CommonCode.FAIL,null);
        }
        //页面id
        String pageId = cmsPageResult.getCmsPage().getPageId();
        //页面url
        String pageUrl = previewUrl + pageId;
        return new CoursePublishResult(CommonCode.SUCCESS,pageUrl);
    }

    /**
     * 课程发布
     * @param courseId
     * @return
     */
    @Transactional
    public CoursePublishResult publish(String courseId){
        //查询课程信息
        CourseBase courseBase = findCourseById(courseId);
        //准备页面信息
        CmsPage cmsPage = new CmsPage();
        cmsPage.setSiteId(publish_siteId);//站点id
        //http://localhost:31200/course/courseview/courseId
        cmsPage.setDataUrl(publish_dataUrlPre+courseId);//数据模型url
        cmsPage.setPageName(courseId+".html");//页面名称
        cmsPage.setPageAliase(courseBase.getName());//页面别名，就是课程名称
        cmsPage.setPagePhysicalPath(publish_page_physicalpath);//页面物理路径
        cmsPage.setPageWebPath(publish_page_webpath);//页面webpath
        cmsPage.setTemplateId(publish_templateId);//页面模板id
        //feign远程调用cms一键发布接口将课程详情页面发布到服务器
        CmsPostPageResult cmsPostPageResult = cmsPageClient.postPageQuick(cmsPage);
        if (!cmsPostPageResult.isSuccess()){
            return new CoursePublishResult(CommonCode.FAIL,null);
        }
        //保存课程的发布状态为"已发布 202002"
        CourseBase rCourseBase = saveCoursePubState(courseId);
        if(rCourseBase == null){
            return new CoursePublishResult(CommonCode.FAIL,null);
        }

        //保存课程索引信息
        //先创建一个coursePub对象
        CoursePub coursePub = createCoursePub(courseId);
        //将coursePub对象保存到数据库
        saveCoursePub(courseId,coursePub);
        //缓存课程的信息
        //...
        //向TeachplanMediaPub中保存课程媒资信息
        saveTeachplanMediaPub(courseId);
        //得到页面的url
        String pageUrl = cmsPostPageResult.getPageUrl();
        return new CoursePublishResult(CommonCode.SUCCESS,pageUrl);
    }

    /**
     * 保存课程计划媒资信息
     */
    private void saveTeachplanMediaPub(String courseId){
        //查询课程媒资信息
        List<TeachplanMedia> teachplanMediaList = teachplanMediaRepository.findByCourseId(courseId);
        //将课程计划媒资信息存储待索引表
        teachplanMediaPubRepository.deleteByCourseId(courseId);
        List<TeachPlanMediaPub> teachplanMediaPubList = new ArrayList<>();
        //将teachplanMediaPubList中的数据放到TeachPlanMediaPubs中
        for(TeachplanMedia teachplanMedia:teachplanMediaList){
            TeachPlanMediaPub teachplanMediaPub =new TeachPlanMediaPub();
            BeanUtils.copyProperties(teachplanMedia,teachplanMediaPub);
            teachplanMediaPubList.add(teachplanMediaPub);
        } teachplanMediaPubRepository.saveAll(teachplanMediaPubList);
    }

    /**
     * 更改课程发布状态为已发布 '202002'
     * @param courseId
     * @return
     */
    private CourseBase saveCoursePubState(String courseId){
        CourseBase courseBase = findCourseById(courseId);
        //更改课程发布状态
        courseBase.setStatus("202002");
        CourseBase save = courseBaseRepository.save(courseBase);
        return save;
    }

    /**
     * 将coursePub对象保存到数据库
     * @param courseId
     * @param coursePub
     * @return
     */
    private CoursePub saveCoursePub(String courseId, CoursePub coursePub){
        CoursePub coursePubNew = null;
        //根据课程id查询coursePub
        Optional<CoursePub> optional = coursePubRepository.findById(courseId);
        if (optional.isPresent()){
            coursePubNew = optional.get();
        }
        coursePubNew = new CoursePub();
        //把形参coursePub对象信息保存到局部变量coursePubNew中
        BeanUtils.copyProperties(coursePub,coursePubNew);
        coursePubNew.setId(courseId);
        //设置时间戳，给logStash使用
        coursePubNew.setTimestamp(new Date());
        //发布时间
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
        String date = simpleDateFormat.format(new Date());
        coursePubNew.setPubTime(date);
        CoursePub save = coursePubRepository.save(coursePubNew);
        return save;
    }

    /**
     * 创建coursePub对象
     * @param courseId
     * @return
     */
    private CoursePub createCoursePub(String courseId){
        CoursePub coursePub = new CoursePub();
        //根据courseId查询Course_Base
        Optional<CourseBase> rCourseBase = courseBaseRepository.findById(courseId);
        if (rCourseBase.isPresent()){
            CourseBase courseBase = rCourseBase.get();
            BeanUtils.copyProperties(courseBase,coursePub);
        }
        //根据courseId查询Course_Pic
        Optional<CoursePic> rCoursePic = coursePicRepository.findById(courseId);
        if (rCoursePic.isPresent()){
            CoursePic coursePic = rCoursePic.get();
            BeanUtils.copyProperties(coursePic,coursePub);
        }
        //根据courseId查询Course_Market
        Optional<CourseMarket> rCourseMarket = courseMarketRepository.findById(courseId);
        if (rCourseMarket.isPresent()){
            CourseMarket courseMarket = rCourseMarket.get();
            BeanUtils.copyProperties(courseMarket,coursePub);
        }
        //根据courseId查询teachPlan
        TeachplanNode teachplanNode = teachplanMapper.selectList(courseId);
        String jsonString = JSON.toJSONString(teachplanNode);
        //将课程计划信息json串保存到 course_pub中
        coursePub.setTeachplan(jsonString);
        return coursePub;
    }
}
